<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>智慧电厂SIS系统 - 3D设备监控</title>
    <style>
        body { margin: 0; font-family: Arial, sans-serif; }
        canvas { display: block; }
        .status-panel { 
            position: absolute; 
            top: 20px; 
            left: 20px; 
            background: rgba(0,0,0,0.7); 
            color: white; 
            padding: 15px; 
            border-radius: 8px;
            z-index: 100;
            min-width: 200px;
        }
        .alert { color: #ff4444; font-weight: bold; }
        .equipment-panel {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(0,0,0,0.8);
            color: white;
            padding: 15px;
            border-radius: 8px;
            width: 300px;
            z-index: 100;
            display: none;
            box-shadow: 0 0 10px rgba(0,0,0,0.5);
        }
        .equipment-panel h3 { 
            margin-top: 0;
            border-bottom: 1px solid #444;
            padding-bottom: 8px;
        }
        .param-row {
            display: flex;
            justify-content: space-between;
            margin: 8px 0;
        }
        .param-name { font-weight: bold; }
        .param-value { text-align: right; }
        .alarm { color: #ff4444; }
        .normal { color: #4CAF50; }
        @keyframes pulse {
            0% { opacity: 0.6; }
            50% { opacity: 1; }
            100% { opacity: 0.6; }
        }
        .pulse-alarm {
            animation: pulse 1.5s infinite;
        }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/controls/OrbitControls.js"></script>
</head>
<body>
    <div class="status-panel">
        <h3>系统状态监控</h3>
        <div class="param-row">
            <span class="param-name">实时测点:</span>
            <span class="param-value"><span id="pointCount">0</span>/<span id="totalPoints">2000+</span></span>
        </div>
        <div class="param-row">
            <span class="param-name">系统状态:</span>
            <span class="param-value" id="systemStatus">正常</span>
        </div>
        <p class="alert" id="alertArea"></p>
    </div>

    <div class="equipment-panel" id="equipmentPanel">
        <h3 id="equipmentTitle">设备详情</h3>
        <div id="equipmentContent"></div>
    </div>

    <script>
        // 初始化场景
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x1a1a2e);

        // 添加网格辅助线
        const gridHelper = new THREE.GridHelper(100, 20, 0x333333, 0x222222);
        scene.add(gridHelper);

        // 初始化相机
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.z = 50;
        camera.position.y = 20;
        camera.lookAt(0, 0, 0);

        // 初始化渲染器
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 添加轨道控制器
        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;

        // 添加光源
        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(50, 100, 50);
        scene.add(directionalLight);

        // 创建设备模型
        function createBoiler() {
            const group = new THREE.Group();
            group.position.set(-20, 10, 0);
            group.name = 'boiler';

            // 锅炉主体
            const geometry = new THREE.CylinderGeometry(8, 10, 20, 32);
            const material = new THREE.MeshStandardMaterial({ 
                color: 0x4a4a4a,
                emissive: 0x000000,
                emissiveIntensity: 0
            });
            const mesh = new THREE.Mesh(geometry, material);
            group.add(mesh);

            // 管道
            const pipeGeometry = new THREE.CylinderGeometry(2, 2, 15, 32);
            const pipe = new THREE.Mesh(pipeGeometry, material);
            pipe.position.set(0, 20, 0);
            pipe.rotation.z = Math.PI / 2;
            group.add(pipe);

            // 状态指示器
            const indicatorGeometry = new THREE.SphereGeometry(1.5, 16, 16);
            const indicatorMaterial = new THREE.MeshStandardMaterial({ 
                color: 0x00ff00,
                emissive: 0x00aa00,
                emissiveIntensity: 0.3
            });
            const indicator = new THREE.Mesh(indicatorGeometry, indicatorMaterial);
            indicator.position.set(12, 10, 0);
            group.add(indicator);

            return group;
        }

        function createTurbine() {
            const group = new THREE.Group();
            group.position.set(20, 8, 0);
            group.name = 'turbine';

            // 涡轮主体
            const geometry = new THREE.BoxGeometry(15, 10, 15);
            const material = new THREE.MeshStandardMaterial({ 
                color: 0x5d5d5d,
                emissive: 0x000000,
                emissiveIntensity: 0
            });
            const mesh = new THREE.Mesh(geometry, material);
            group.add(mesh);

            // 叶片
            const bladeGeometry = new THREE.BoxGeometry(12, 2, 2);
            const bladeMaterial = new THREE.MeshStandardMaterial({ color: 0x777777 });
            const blade1 = new THREE.Mesh(bladeGeometry, bladeMaterial);
            blade1.position.set(12, 0, 0);
            group.add(blade1);

            const blade2 = new THREE.Mesh(bladeGeometry, bladeMaterial);
            blade2.position.set(12, 0, 0);
            blade2.rotation.z = Math.PI / 2;
            group.add(blade2);

            return group;
        }

        // 添加设备到场景
        const boiler = createBoiler();
        scene.add(boiler);

        const turbine = createTurbine();
        scene.add(turbine);

        // 状态判断标准
        const STATUS_THRESHOLDS = {
            BOILER: {
                TEMP_ALARM: 400,
                PRESSURE_ALARM: 15
            },
            TURBINE: {
                VIBRATION_ALARM: 0.5
            }
        };

        // 当前选中设备
        let selectedEquipment = null;

        // 统一状态判断
        function checkSystemStatus(data) {
            const alarmDevices = [];
            let isNormal = true;

            data.points.forEach(point => {
                let isAlarm = false;
                
                if (point.device_id.includes('BOILER')) {
                    if (point.status === "ALARM" || 
                        point.temperature > STATUS_THRESHOLDS.BOILER.TEMP_ALARM || 
                        point.pressure > STATUS_THRESHOLDS.BOILER.PRESSURE_ALARM) {
                        isAlarm = true;
                    }
                } 
                else if (point.device_id.includes('TURBINE')) {
                    if (point.status === "ALARM" || 
                        point.vibration > STATUS_THRESHOLDS.TURBINE.VIBRATION_ALARM) {
                        isAlarm = true;
                    }
                }

                if (isAlarm) {
                    alarmDevices.push(point.device_id);
                    isNormal = false;
                }
            });

            return {
                isNormal,
                alarmDevices,
                timestamp: new Date().toLocaleTimeString(),
                rawData: data
            };
        }

        // 更新系统状态UI
        function updateSystemStatusUI(status) {
            const statusElement = document.getElementById('systemStatus');
            const alertElement = document.getElementById('alertArea');
            
            document.getElementById('pointCount').textContent = status.rawData.point_count;
            
            if (status.isNormal) {
                statusElement.textContent = "正常";
                statusElement.className = "param-value normal";
                alertElement.textContent = "";
            } else {
                statusElement.textContent = "异常";
                statusElement.className = "param-value alarm";
                alertElement.innerHTML = `⚠️ 异常设备: ${status.alarmDevices.join(', ')}<br>检测时间: ${status.timestamp}`;
            }

            // 如果当前有选中的设备，更新其面板
            if (selectedEquipment) {
                updateEquipmentPanel(selectedEquipment, status.rawData);
            }
        }

        // 更新3D模型状态
        function update3DModelStatus(status) {
            const boilerIndicator = boiler.children[2];
            const turbineMain = turbine.children[0];
            
            // 锅炉状态
            if (boilerIndicator) {
                if (!status.isNormal && status.alarmDevices.some(d => d.includes('BOILER'))) {
                    boilerIndicator.material.color.setHex(0xff0000);
                    boilerIndicator.material.emissive.setHex(0xff0000);
                    boilerIndicator.material.emissiveIntensity = 0.5;
                } else {
                    boilerIndicator.material.color.setHex(0x00ff00);
                    boilerIndicator.material.emissive.setHex(0x00aa00);
                    boilerIndicator.material.emissiveIntensity = 0.3;
                }
            }
            
            // 涡轮状态
            if (turbineMain) {
                if (!status.isNormal && status.alarmDevices.some(d => d.includes('TURBINE'))) {
                    turbineMain.material.color.setHex(0xff4444);
                    turbineMain.material.emissive.setHex(0xff0000);
                    turbineMain.material.emissiveIntensity = 0.3;
                } else {
                    turbineMain.material.color.setHex(0x5d5d5d);
                    turbineMain.material.emissive.setHex(0x000000);
                    turbineMain.material.emissiveIntensity = 0;
                }
            }
        }

        // 加载实时数据（不使用工业机器时）
        function loadRealData() {
            fetch(`data.json?t=${Date.now()}`)
                .then(response => {
                    if (!response.ok) return generateMockData();
                    return response.json();
                })
                .then(data => {
                    const latestData = data[data.length - 1];
                    const status = checkSystemStatus(latestData);
                    
                    updateSystemStatusUI(status);
                    update3DModelStatus(status);
                    
                    // 更新总测点数
                    document.getElementById('totalPoints').textContent = 
                        Math.max(2000, latestData.point_count * 2);
                })
                .catch(error => {
                    console.error('加载失败:', error);
                    const mockData = {
                        point_count: 42,
                        points: [
                            {device_id: "BOILER_1", status: "NORMAL", temperature: 320, pressure: 12.5},
                            {device_id: "TURBINE_1", status: "NORMAL", vibration: 0.02}
                        ]
                    };
                    const status = checkSystemStatus(mockData);
                    updateSystemStatusUI(status);
                    update3DModelStatus(status);
                });
        }

        // 从JSON文件加载实时数据（使用工业机器时）
        // function loadRealData() {
        //     fetch('data.json')
        //         .then(response => {
        //             if (!response.ok) {
        //                 throw new Error('Network response was not ok');
        //             }
        //             return response.json();
        //         })
        //         .then(data => {
        //             // 更新测点数量
        //             pointCount = data.point_count;
        //             pointCountElement.textContent = pointCount;

        //             // 检查是否有告警
        //             const alarmPoints = data.points.filter(point => point.is_alarm);
        //             if (alarmPoints.length > 0) {
        //                 alertAreaElement.textContent = `⚠️ 检测到 ${alarmPoints.length} 个设备异常！`;
        //                 systemStatusElement.textContent = '异常';
        //                 systemStatusElement.style.color = '#ff4444';

        //                 // 更新3D模型中的告警指示器
        //                 if (boiler.children[2]) {
        //                     boiler.children[2].material.color.set(0xff0000);
        //                 }
        //             } else {
        //                 alertAreaElement.textContent = '';
        //                 systemStatusElement.textContent = '正常';
        //                 systemStatusElement.style.color = 'white';

        //                 // 更新3D模型中的正常指示器
        //                 if (boiler.children[2]) {
        //                     boiler.children[2].material.color.set(0x00ff00);
        //                 }
        //             }
        //         })
        //         .catch(error => {
        //             console.error('Error loading real data:', error);
        //         });
        // }

        // 更新设备信息面板
        function updateEquipmentPanel(equipment, data) {
            const deviceType = equipment.name.toUpperCase();
            const deviceData = data.points.find(p => p.device_id.startsWith(deviceType));
            const panel = document.getElementById('equipmentPanel');
            const title = document.getElementById('equipmentTitle');
            const content = document.getElementById('equipmentContent');

            if (!deviceData) {
                content.innerHTML = `<p>未找到实时数据</p>`;
                return;
            }

            const isNormal = checkDeviceStatus(deviceData);
            const time = new Date().toLocaleTimeString();
            
            title.textContent = equipment.name === 'boiler' ? '主锅炉状态' : '汽轮机状态';
            
            let html = `
                <div class="param-row">
                    <span class="param-name">状态:</span>
                    <span class="param-value ${isNormal ? 'normal' : 'alarm'}">
                        ${isNormal ? '正常' : '异常'}
                    </span>
                </div>
                <div class="param-row">
                    <span class="param-name">更新时间:</span>
                    <span class="param-value">${time}</span>
                </div>
            `;
            
            if (equipment.name === 'boiler') {
                html += `
                    <div class="param-row">
                        <span class="param-name">温度:</span>
                        <span class="param-value ${deviceData.temperature > STATUS_THRESHOLDS.BOILER.TEMP_ALARM ? 'alarm' : ''}">
                            ${deviceData.temperature.toFixed(1)}°C 
                            ${deviceData.temperature > STATUS_THRESHOLDS.BOILER.TEMP_ALARM ? '⚠️' : ''}
                        </span>
                    </div>
                    <div class="param-row">
                        <span class="param-name">压力:</span>
                        <span class="param-value ${deviceData.pressure > STATUS_THRESHOLDS.BOILER.PRESSURE_ALARM ? 'alarm' : ''}">
                            ${deviceData.pressure.toFixed(2)} MPa 
                            ${deviceData.pressure > STATUS_THRESHOLDS.BOILER.PRESSURE_ALARM ? '⚠️' : ''}
                        </span>
                    </div>
                `;
            } else {
                html += `
                    <div class="param-row">
                        <span class="param-name">振动:</span>
                        <span class="param-value ${deviceData.vibration > STATUS_THRESHOLDS.TURBINE.VIBRATION_ALARM ? 'alarm' : ''}">
                            ${deviceData.vibration.toFixed(3)} mm/s 
                            ${deviceData.vibration > STATUS_THRESHOLDS.TURBINE.VIBRATION_ALARM ? '⚠️' : ''}
                        </span>
                    </div>
                    <div class="param-row">
                        <span class="param-name">转速:</span>
                        <span class="param-value">3000 rpm</span>
                    </div>
                `;
            }
            
            content.innerHTML = html;
            panel.style.display = 'block';
        }

        function checkDeviceStatus(deviceData) {
            if (deviceData.status === "ALARM") return false;
            
            if (deviceData.device_id.includes('BOILER')) {
                return deviceData.temperature <= STATUS_THRESHOLDS.BOILER.TEMP_ALARM && 
                       deviceData.pressure <= STATUS_THRESHOLDS.BOILER.PRESSURE_ALARM;
            }
            
            if (deviceData.device_id.includes('TURBINE')) {
                return deviceData.vibration <= STATUS_THRESHOLDS.TURBINE.VIBRATION_ALARM;
            }
            
            return true;
        }

        // 交互事件
        function onMouseClick(event) {
            const mouse = new THREE.Vector2(
                (event.clientX / window.innerWidth) * 2 - 1,
                -(event.clientY / window.innerHeight) * 2 + 1
            );

            raycaster.setFromCamera(mouse, camera);
            const intersects = raycaster.intersectObjects(scene.children, true);

            if (intersects.length > 0) {
                const equipment = findParentWithName(intersects[0].object);
                if (equipment) {
                    selectEquipment(equipment);
                    return;
                }
            }
            
            // 点击空白处取消选择
            deselectEquipment();
        }

        function findParentWithName(object) {
            if (object.name && (object.name === 'boiler' || object.name === 'turbine')) {
                return object;
            }
            return object.parent ? findParentWithName(object.parent) : null;
        }

        // 选中设备
        function selectEquipment(equipment) {
            // 取消之前的选择
            if (selectedEquipment) {
                resetEquipmentColor(selectedEquipment);
            }
            
            // 设置新选择
            selectedEquipment = equipment;
            highlightEquipment(equipment);
            
            // 立即加载数据并显示面板
            fetch(`data.json?t=${Date.now()}`)
                .then(response => response.json())
                .then(data => {
                    updateEquipmentPanel(equipment, data[data.length - 1]);
                })
                .catch(error => {
                    console.error('加载设备数据失败:', error);
                    document.getElementById('equipmentContent').innerHTML = 
                        `<p>无法加载实时数据</p>`;
                    document.getElementById('equipmentPanel').style.display = 'block';
                });
        }

        // 取消选择
        function deselectEquipment() {
            if (selectedEquipment) {
                resetEquipmentColor(selectedEquipment);
                selectedEquipment = null;
            }
            document.getElementById('equipmentPanel').style.display = 'none';
        }

        function highlightEquipment(equipment) {
            const target = equipment.children[0];
            if (target) {
                target.material.color.setHex(0xffff00);
                target.material.emissive.setHex(0xffff00);
                target.material.emissiveIntensity = 0.2;
            }
        }

        function resetEquipmentColor(equipment) {
            const target = equipment.children[0];
            if (target) {
                target.material.color.setHex(
                    equipment.name === 'boiler' ? 0x4a4a4a : 0x5d5d5d
                );
                target.material.emissive.setHex(0x000000);
                target.material.emissiveIntensity = 0;
            }
        }

        // 模拟数据生成
        function generateMockData() {
            return {
                point_count: Math.floor(Math.random() * 50) + 100,
                points: [
                    {
                        device_id: "BOILER_1",
                        status: Math.random() > 0.8 ? "ALARM" : "NORMAL",
                        temperature: Math.random() * 100 + 300,
                        pressure: Math.random() * 5 + 10
                    },
                    {
                        device_id: "TURBINE_1",
                        status: Math.random() > 0.9 ? "ALARM" : "NORMAL",
                        vibration: Math.random() * 0.5
                    }
                ]
            };
        }

        // 射线检测器
        const raycaster = new THREE.Raycaster();

        // 启动系统
        setInterval(loadRealData, 2000);
        loadRealData();

        function animate() {
            requestAnimationFrame(animate);
            
            // 涡轮旋转动画
            if (turbine.children[1]) {
                const rotationSpeed = selectedEquipment === turbine ? 0.1 : 0.05;
                turbine.children[1].rotation.y += rotationSpeed;
                turbine.children[2].rotation.y += rotationSpeed;
            }
            
            controls.update();
            renderer.render(scene, camera);
        }

        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        window.addEventListener('click', onMouseClick);
        animate();
    </script>
</body>
</html>